using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Math.Geometry;
using FlatRedBall.Input;

using Microsoft.Xna.Framework;

using Xzipit.Utilities;
using Xzipit.Utilities.Gestures;

namespace Xzipit.GameObjects
{
    public abstract class Obstacle : PositionedObject
    {
        #region Fields
        protected bool _enabled;
        protected Polygon _collision;
        protected Sprite _sprite;
        protected Sprite _tooltip;
        protected string _contentManagerName;

        private bool _partialFade;
        #endregion

        #region Properties
        public Polygon Collision
        {
            get { return _collision; }
        }

        public bool Enabled
        {
            get { return _enabled; }
            set { _enabled = value; }
        }

        public virtual float Alpha
        {
            get { return _sprite.Alpha; }
            set
            {
                _sprite.Alpha = value;
                _tooltip.Alpha = value;
            }
        }

        public virtual float AlphaRate
        {
            get { return _sprite.AlphaRate; }
            set
            {
                _sprite.AlphaRate = value;
                _tooltip.AlphaRate = value;
            }
        }
        #endregion

        #region Methods

        #region Initialization
        protected abstract void Initialize(bool addToManagers);

        public virtual void AddToManagers(float xScale, float yScale)
        {
            // Attachs the sprite to the given Obstacle object.
            _sprite.AttachTo(this, false);

            // Scales the sprite so it is the proper size.
            _sprite.PixelScale();

            // Sets up a collision rectangle based on the length and width
            // of the sprite of the Obstacle.
            _collision = Polygon.CreateRectangle(_sprite.ScaleX * xScale, _sprite.ScaleY * yScale);
            ShapeManager.AddPolygon(_collision);
            _collision.AttachTo(_sprite, false);
            _collision.Visible = false;

            // Makes the Obstacle active by default.
            _enabled = true;
            _partialFade = false;
        }
        #endregion

        #region Abstract Methods
        public abstract void Activity(GameGesture zipGesture, double t);
        public abstract void Collide(double t);

        #endregion

        #region Destroy

        public virtual void Destroy()
        {
            SpriteManager.RemovePositionedObject(this);
            ShapeManager.Remove(_collision);
            SpriteManager.RemoveSprite(_sprite);
            SpriteManager.RemoveSprite(_tooltip);

        }

        #endregion

        public virtual void Stop()
        {
            this.Velocity = Vector3.Zero;
            this.Enabled = false;
            _sprite.Animate = false;
        }

        #region Fade

        public virtual void FadeOut()
        {
            this.AlphaRate = -GameProperties.ALPHA_RATE;
            _partialFade = false;
        }

        public virtual void PartialFadeOut()
        {
            this.AlphaRate = -GameProperties.ALPHA_RATE;
            _partialFade = true;
        }

        public virtual void FadeIn()
        {
            this.AlphaRate = GameProperties.ALPHA_RATE;
        }

        public virtual bool DoneFading()
        {
            if (this.Alpha >= 1.0f && this.AlphaRate == GameProperties.ALPHA_RATE)
            {
                this.Alpha = 1.0f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else if (_partialFade
                && this.Alpha <= .15f && this.AlphaRate == -GameProperties.ALPHA_RATE)
            {
                this.Alpha = .15f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else if (!_partialFade
                && this.Alpha <= 0.0f && this.AlphaRate == -GameProperties.ALPHA_RATE)
            {
                this.Alpha = 0.0f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region Tooltip
        protected abstract void PlayTooltip();

        public void SetTooltip(bool val)
        {
            if (val)
            {
                _tooltip.Visible = true;
            }
            else
            {
                _tooltip.Visible = false;
            }
        }

        protected void SetTooltip(string name)
        {
            _tooltip = SpriteManager.AddSprite(@"Content\MenuObjects\Indicators\" + name, _contentManagerName);
            _tooltip.AttachTo(this, false);

            _tooltip.PixelScale();
            _tooltip.ScaleX *= 2;
            _tooltip.ScaleY *= 2;
            _tooltip.Visible = false;
        }
        #endregion

        #endregion
    }
}
